#/src/views/PortfolioView.py
import json
from flask import request, g, Blueprint, json, Response
from shared.Authentication import Auth
from shared.Updateprice import Update
from models import PortfolioModel, PortfolioSchema
from models import MarketModel, MarketSchema
from models import CurrencyModel, CurrencySchema

portfolio_api = Blueprint('portfolio_api', __name__)
portfolio_schema = PortfolioSchema()
market_schema = MarketSchema()

@portfolio_api.route('/', methods=['POST'])
@Auth.auth_required
def create():
  """
  Create Portfolio Function
  """
  req_data = request.get_json()
  data, error = portfolio_schema.load(req_data)  # {'title': 'Second POST', 'contents': 'This is my second post', 'owner_id': 2}

  if error:
    return custom_response(error, 400)
  post = PortfolioModel(data)
  post.save()
  data = portfolio_schema.dump(post).data  # {'title': 'Second POST', 'id': 2, 'created_at': '2020-06-23T14:10:20.194070+00:00', 'contents': 'This is my second post', 'owner_id': 2, 'modified_at': '2020-06-23T14:10:20.194070+00:00'}
  
  return custom_response(data, 201)

@portfolio_api.route('/', methods=['GET'])
@Auth.auth_required
def get_all():
  """
  Get All Portfolios
  """
  posts = PortfolioModel.get_all_portfolios()
  data = portfolio_schema.dump(posts, many=True).data
  return custom_response(data, 200)

@portfolio_api.route('/<int:portfolio_code>', methods=['GET'])
def get_one(portfolio_code):
  """
  Get A portfolio
  """
  post = PortfolioModel.get_one_portfolio(portfolio_code)
  if not post:
    return custom_response({'error': 'post not found'}, 404)
  data = portfolio_schema.dump(post).data
  return custom_response(data, 200)

@portfolio_api.route('/<int:portfolio_id>', methods=['PUT'])
@Auth.auth_required
def update(portfolio_id):
  """
  Update A Portfolio
  """
  req_data = request.get_json()
  post = PortfolioModel.get_one_portfolio(portfolio_id)
  if not post:
    return custom_response({'error': 'post not found'}, 404)
  data = portfolio_schema.dump(post).data
  # if data.get('market_id') != g.market.get('id'):
  #   return custom_response({'error': 'permission denied'}, 400)
  
  data, error = portfolio_schema.load(req_data, partial=True)
  if error:
    return custom_response(error, 400)
  post.update(data)
  
  data = portfolio_schema.dump(post).data
  return custom_response(data, 200)

@portfolio_api.route('/<int:portfolio_id>', methods=['DELETE'])
@Auth.auth_required
def delete(portfolio_id):
  """
  Delete A Portfolio
  """
  post = PortfolioModel.get_one_portfolio(portfolio_id)
  if not post:
    return custom_response({'error': 'post not found'}, 404)
  data = portfolio_schema.dump(post).data
  if data.get('market_id') != g.markets.get('id'):
    return custom_response({'error': 'permission denied'}, 400)

  post.delete()
  return custom_response({'message': 'deleted'}, 204)
  

def custom_response(res, status_code):
  """
  Custom Response Function
  """
  return Response(
    mimetype="application/json",
    response=json.dumps(res),
    status=status_code
  )



@portfolio_api.route('/update', methods=['GET'])
def updatePrice():
  """
  Update Portfolio Price Function
  """
  posts = PortfolioModel.query.all()
  data = portfolio_schema.dump(posts, many=True).data
  
  cl = []
  for p in posts:
    cl.append(MarketModel.get_one_market(p.market_id).mtPre + '.' + p.code)
  priceJs = json.loads(Update.update_price(cl))
  
  for d in data:
    for p in priceJs["data"]:
      if p[0] == d["code"]:
        d["last_price"] = p[1]
        d["prev_close_price"] = p[2]
        d["volume"] = p[3]
        d["volume_ratio"] = p[4]
        d["turnover"] = round(p[5], 0)
        d["turnover_rate"] = round(p[6], 1)
        d["dividend_ratio_ttm"] = p[7]
        d["change_rate"] = round(p[8], 2)

  for d in data:
    for p in posts:
      if p.code == d["code"]:
        p.update(d)

  return custom_response(priceJs, 200)